package com.siao.starling.mvc
{
	import com.siao.errors.StateError;
	import com.siao.starling.display.LayoutElement;
	import com.siao.starling.mvc.core.IState;
	import com.siao.starling.mvc.managers.ModelManager;
	
	import starling.events.Event;
	
	[Event(name="change", type="starling.events.Event")]
	
	/**
	 * 模块（状态管理器）
	 * @author SiaoLeon
	 */
	public class Module extends LayoutElement
	{
		// -------------------------------------------------------------------------------------------------------- 静态常量
		
		// -------------------------------------------------------------------------------------------------------- 静态变量
		
		// -------------------------------------------------------------------------------------------------------- 静态方法
		
		// -------------------------------------------------------------------------------------------------------- 静态函数
		
		// -------------------------------------------------------------------------------------------------------- 属性
		
		private var _currentState:IState;
		
		/**
		 * 当前状态
		 * @return
		 */
		public function get currentState():IState
		{
			return this._currentState;
		}
		
		private var _rootState:IState;
		
		/**
		 * 根状态
		 * @return
		 */
		public function get rootState():IState
		{
			return this._rootState;
		}
		
		public function set rootState(state:IState):void
		{
			this._rootState = state;
			
			if (this.stage == null)
			{
				this.closeAllState();
			}
			else
			{
				this.switchState(this.rootState.key);
			}
		}
		
		// -------------------------------------------------------------------------------------------------------- 变量
		
		// -------------------------------------------------------------------------------------------------------- 构造
		
		/**
		 * 构造函数
		 */
		public function Module(root:IState=null)
		{
			this._rootState = root;
		}
		
		// -------------------------------------------------------------------------------------------------------- 方法
		
		/**
		 * 获取状态
		 * @param key 状态标识
		 * @return
		 */
		public function getState(key:Object):IState
		{
			function search(state:IState):IState
			{
				if (state.key == key) {
					return state;
				}
				
				var result:IState = null;
				
				for (var i:int = 0; i < state.childs.length; i++)
				{
					var child:IState = state.childs.element(i) as IState;
					
					result = search(child);
					
					if (result != null)
					{
						break;
					}
				}
				
				return result;
			}
			
			return search(this.rootState);
		}
		
		/**
		 * 关闭所有已打开的状态
		 */
		public function closeAllState():void
		{
			this.reset();
			
			ModelManager.instance.clear();
			
			this.dispatchEvent(new Event(Event.CHANGE));
		}
		
		/**
		 * 切换状态
		 * @param key 状态标识
		 * @throws StateError 未找到该标识的状态时抛出错误
		 */
		public function switchState(key:Object):void
		{
			var state:IState = this.getState(key);
			
			if (state == null)
			{
				throw new StateError(StateError.NOTFOUND, key);
			}
			
			var route:Array = (this.currentState == null) ? null : this.currentState.getPath(state);
			var parent:IState;
			
			if (route == null)
			{
				//当前状态场景与目标状态场景不处于同一父级
				for each (parent in state.path)
				{
					parent.module = this;
					parent.onInit();
				}
				
				this.reset();
				
				this._currentState = state;
				
				for each (parent in state.path)
				{
					parent.onEnter();
				}
			}
			else
			{
				//当前状态场景与目标状态场景处于同一父级
				
				var current:IState = this.currentState;
				
				for each (parent in state.path)
				{
					if (current.path.indexOf(parent) < 0)
					{
						parent.module = this;
						parent.onInit();
					}
				}
				
				for each (parent in route)
				{
					if (current.path.indexOf(parent) >= 0 && state.path.indexOf(parent) >= 0)
					{
						continue;
					}
					
					if (current.path.indexOf(parent) > 0)
					{
						parent.onExit();
						parent.module = null;
					}
					
					this._currentState = state;
					
					if (state.path.indexOf(parent) > 0)
					{
						parent.onEnter();
					}
				}
			}
			
			ModelManager.instance.clear();
			
			this.dispatchEvent(new Event(Event.CHANGE));
		}
		
		// -------------------------------------------------------------------------------------------------------- 函数
		
		override protected function onAddedToStage():void
		{
			if (this.stage != null && this.rootState != null)
			{
				this.switchState(this.rootState.key);
			}
		}
		
		override protected function onRemovedFromStage():void
		{
			this.closeAllState();
		}
		
		/**
		 * 重置
		 */
		private function reset():void
		{
			if (this.currentState == null)
			{
				return;
			}
			
			var path:Array = this.currentState.path.concat().reverse();
			
			for each (var state:IState in path)
			{
				state.onExit();
				state.module = null;
			}
			
			this._currentState = null;
		}
	
	}
}
